home *** CD-ROM | disk | FTP | other *** search
/ The Original Shareware 1.1 / The Original Shareware (WeMake CDs)(Volume 1.1)(CDs, Inc)(1993).iso / 6 / clantutr.zip / LESSON3 < prev    next >
Text File  |  1985-12-28  |  15KB  |  419 lines

  1. .NT
  2.  A NOTE ABOUT THE LESSONS in C 
  3. .b4-24
  4. .R5C4
  5. These were written while the author was ~Ilearning~N  the language and since
  6. .R6C4
  7. they  are  ~Ifree~N ( to  copy  and/or  distribute ) there  is  a money-back
  8. .R7C4
  9. guarantee on the accuracy of each and every statement in the lessons (!)
  10. .R9C4
  11. The  ~Idisplay~N  program was written ( in C ) in order to provide a vehicle
  12. .R10C4
  13. for displaying the lessons.
  14. .R12C5
  15. .B
  16. P.J.Ponzo
  17. .B
  18. Dept. of Applied Math
  19. .B
  20. Univ. of Waterloo
  21. .B
  22. Ontario N2L 3G1
  23. .K16,30
  24. PonzoTUTOR
  25. .WNT
  26.   FUNCTIONS()  
  27. .R4C1
  28. ~Vmain()~b~I~W {~N
  29. ~b~Ifloat x,y,a;~N
  30. ~b~Iprintf("\n Enter two numbers (separated by a space) : ");~N
  31. ~b~Iscanf("%f%f",x,y);~N
  32. ~b~Ia=average(x,y);~N
  33. ~b~Iprintf("\n The average of %f and %f is %f",x,y,a);~N
  34. ~b~I}~N
  35.  
  36.     When we begin our C program with ~b~Imain()~N we are defining a
  37.     ~Ifunction~N. Execution of our C program will ~Ibegin~N at the 
  38.     statements which make up this function (and it is this property
  39.     which makes the name ~b~Imain~N special).
  40. .W
  41. .R4C1
  42. ~b~Imain() {~N
  43. ~Vfloat x,y,a;~N
  44. ~Vprintf("\n Enter two numbers (separated by a space) : ");~N
  45. .R12C1
  46.                                                                            
  47.                                                                            
  48.                                                                            
  49.                                                                            
  50. .R12C1
  51.     Here we define three ~b~Ifloat~N variables called ~b~Ix~N, ~b~Iy~N and 
  52.     ~b~Ia~N and ~b~Iprintf~N instructions asking for ~b~Ix~N and ~b~Iy~N.
  53.     Note that the user must enter a ~Ispace~N to separate the two numbers.
  54.     (Pressing the ~Itab~N key between numbers will also 'separate' them).
  55.     ~b~Iprintf()~N is a function, just like ~b~Imain()~N. When we invoke
  56.     this function we pass to it a ~Iformat~N string (between quotes) and
  57.     (sometimes) a list of variables to be printed. In this example there
  58.     is ~Ionly~N the ~Iformat string~N (which prints a ~b~In~Newline first):
  59.  
  60.            ~V"\n Enter two numbers (separated by a space) : "~N
  61. .W
  62. .R5C1
  63. ~b~Ifloat x,y,a;~N
  64. ~b~Iprintf("\n Enter two numbers (separated by a space) : ");~N
  65. ~Vscanf("%f%f",x,y);~N    
  66. .R12C1
  67.                                                                            
  68.                                                                            
  69.  
  70.  
  71. .w                                                                           
  72. .R12C1
  73.     Now we use the ~Ifunction~N ~b~Iscanf()~N to input the two numbers    
  74.     ~b~Ix~N and ~b~Iy~N. Note that ~b~Iscanf()~N also requires a ~Iformat~N  
  75.     string (namely ~b~I"%f%f"~N) and a variable list ~b~Ix,y~N.                    
  76.                                                                            
  77.     ~ICan you pick out the ERROR in this statement?                        ~N
  78.                                                                            
  79.                                                                            
  80.                                                                            
  81.                                                                            
  82.                                                                            
  83.                                                                            
  84. .W
  85. .R16C1
  86.     ~b~I                                                        ~N
  87.     ~b~I  The function scanf() requires that we pass to it the  ~N
  88.     ~b~I  addresses of x and y by using &x and &y...REMEMBER?   ~N
  89.     ~b~I                                                        ~N
  90. .R7C1
  91. ~Vscanf("%f%f",x,y);~N    should be:  ~b~Iscanf("%f%f",~V&x,&y~b~I~W);~N    
  92. .K19,55
  93. REMEMBER!!
  94. .W
  95. .R7C1
  96. ~b~Iscanf("%f%f",&x,&y);~N                                                
  97. ~b~Ia=~Vaverage(x,y)~b~I~W;~N
  98. .w
  99. .R12C1
  100.                                                                            
  101.                                                                            
  102.                                                                            
  103.                                                                            
  104.                                                                            
  105.                                                                            
  106.                                                                            
  107.                                                                            
  108.                                                                            
  109.                                                                            
  110.                                                                            
  111.                                                                            
  112.                                                                            
  113. .w
  114. .R12C1
  115.     Here we see another ~Ifunction~N called ~b~Iaverage()~N. We pass to this
  116.     function the values of two variables, ~b~Ix~N and ~b~Iy~N.
  117.  
  118.     The C language recognizes a ~Ifunction~N by the fact that it is given
  119.     a name (like ~b~Imain~N, ~b~Iscanf~N, ~b~Iprintf~N or ~b~Iaverage~N)
  120.     followed ~Iimmediately~N by parentheses ~b~I(....)~N. Within the ~b~I(~N
  121.     and the ~b~I)~N is information which is passed to the ~Ifunction~N.
  122.     Unlike ~b~Iscanf()~N and ~b~Iprintf()~N (which are included in the C
  123.     library of functions and are available for our use), the function
  124.     which we are calling ~b~Iaverage()~N is one which we must write ourself!
  125. .W
  126. .N
  127. ~b~Imain() {~
  128. ~b~Ifloat x,y,a;~N
  129. ~b~Iprintf("\n Enter two numbers (separated by a space) : ");~N
  130. ~b~Iscanf("%f%f",&x,&y);~N        (note that we've changed to ~b~I&x,&y~N)
  131. ~Va=average(x,y);~N
  132. ~Vprintf("\n The average of %f and %f is %f",x,y,a);~N
  133. ~b~I}~N
  134.     The functions ~b~Iscanf()~N and ~b~Iprintf()~N perform their task and
  135.     ~Ireturn~N nothing, but our ~Ifunction~N ~b~Iaverage()~N is expected to
  136.     ~Ireturn the average~N of the two variable values we passed to it.
  137.  
  138.     In our program above we assign this 'returned average' to the ~b~Ifloat~N
  139.     variable we are calling ~b~Ia~N....and pass to ~b~Iprintf()~N a ~Iformat~N
  140.     string ~b~I"\n The average of %f and %f is %f"~N indicating that we want
  141.     certain text printed (after a ~b~In~Newline) as well as 3 ~b~I%f~Nloat
  142.     numbers.
  143. .w
  144.  
  145.     The variable list which we pass to ~b~Iprintf()~N (namely ~b~Ix,y,a~N)
  146.     tells ~b~Iprintf()~N which 3 ~b~I%f~Nloat values are to replace the 3
  147.     ~b~I%f~N which occur in the 'format' information.
  148. .K19,60
  149. go!go!go!
  150. .WNT
  151.    writing the function average()    
  152.  
  153.     Like the function ~b~Imain()~N, we begin with the name and an opening
  154.     ~b~I{~N. BUT, unlike ~b~Imain()~N, the function ~b~Iaverage~N is to
  155.     ~Ireceive~N two variables....so, ~Ibefore our opening {~N, we write:
  156.  
  157. ~b~Iaverage(x,y)~N
  158. ~b~Ifloat x,y;~N
  159. ~b~I{~N                      the opening ~b~I{~N occurs ~Iafter~N the
  160.                              declaration ~b~Ifloat x,y~N !
  161.  
  162.          ~V                                                       ~N
  163.          ~V THE FIRST STATEMENT IN A FUNCTION  even before the {  ~N
  164.          ~V MUST BE A DECLARATION OF THE ARGUMENT TYPES!          ~N
  165.          ~V                                                       ~N
  166.  
  167.     ...let's continue writing our ~Iaverage()~N function:
  168. .K19,60
  169. GO!GO!GO!
  170. .WN
  171. ~b~Iaverage(x,y)~N
  172. ~b~Ifloat x,y;~N
  173. ~b~I{~N  
  174. ~Vfloat z;~N
  175. ~b~Iz=(x+y)/2;~N
  176. ~b~Ireturn(z);~N
  177. ~b~I}~N
  178.  
  179.     The ~Vfloat z;~N (within the body of our function) declares the
  180.     variable ~Vz~N to be a ~Vfloat~N.
  181. .W
  182. .R4C1
  183. ~b~Ifloat z;~N
  184. ~Vz=(x+y)/2;~N
  185. .R12C1
  186.     ~Vz=(x+y)/2~N assigns to ~Vz~N the average of ~Vx~N and ~Vy~N.
  187. .W
  188. .R5C1
  189. ~b~Iz=(x+y)/2;~N
  190. ~Vreturn(z);~N
  191. .R14C1
  192.     ~Vreturn(z);~N will ~Ireturn~N the value of ~Vz~N (so it can be
  193.     used in our ~b~Imain()~N program.
  194. .WN
  195.     The whole thing, including ~b~Imain()~N, is now:
  196. ~b~Imain() {~N
  197. ~b~Ifloat x,y,a;~N
  198. ~b~Iprintf("\n Enter two numbers (separated by a space) : ");~N
  199. ~b~Iscanf("%f%f",&x,&y);~N   
  200. ~b~Ia=average(x,y);~N
  201. ~b~Iprintf("\n The average of %f and %f is %f",x,y,a);~N
  202. ~b~I}~N
  203. ~b~Iaverage(x,y)~N
  204. ~b~Ifloat x,y;~N
  205. ~b~I{~N  
  206. ~b~Ifloat z;~N
  207. ~b~Iz=(x+y)/2;~n
  208. ~b~Ireturn(z);~N
  209. ~b~I}~N
  210.  
  211.     ...actually, this program won't (quite) work...but let's see how to
  212.     get it to compile and run.
  213. .K19,60
  214. won'twork?
  215. .WN
  216.  
  217.  
  218.  
  219.  
  220.  
  221. .T
  222.    How to COMPILE   
  223. .WN
  224.     We save our program on disk and leave our word processor, giving 
  225.     our program a name: ~Iprogram1.c~N ( note the necessary ~I.c~N ).
  226.  
  227.     Then we would ask the ~IC-compiler~N to compile it, with the command:
  228.  
  229. ~Icc program1~N
  230.  
  231.     With this command the compiler looks for a file on the disk with the
  232.     name ~Iprogram1.c~N ( the extension ~I.c~N being ~IUNDERSTOOD~N! ) and
  233.     generates a file called ~Iprogram1.o~N ( an ~Io~Nbject file).
  234.  
  235.     After the compiler has done its thing it's our turn again.
  236.  
  237.     We ask to ~Ilink~N the ~Io~Nbject file by issuing the command:
  238.  
  239. ~Ilink program1~N
  240.  
  241.     where, again, the extension ( ~I.o~N in this case ) is understood.
  242.  
  243.     The linker works on the ~Iprogram1.o~N file and generates an ~Iexe~Ncutable
  244.     program called:  ~Iprogram1.exe~N
  245.  
  246.     Finally, we may issue the command: ~Iprogram1~N to run our program.
  247. .WN
  248.  
  249.  
  250.  
  251.  
  252.  
  253.     ~INOTE~N: The  commands  necessary  to  ~Icompile~N  and  ~Ilink~N,  and the 
  254.           eventual name of the executable program, may vary from one
  255.           C-compiler to another. On the IBM PC, the (final, compiled)
  256.           program will normally have the extension ~I.exe~N.
  257. .b5-10
  258. .W
  259. .R12C1
  260.     The reason for the 2-step process of ~Icompile~N then ~Ilink~N is that
  261.     we may write (for example) the ~b~Iaverage()~N function separately, and
  262.     ~Icompile~N it separately (generating an ~Io~Nbject file, say ~Iaverage.o~N)
  263.     then ~Ilink~N the ~b~Imain()~N function to the ~b~Iaverage~N function by
  264.     issuing the command: ~Ilink program1 average~N
  265.     (where we have called the ~b~Imain()~N function ~Iprogram1.c~N when we saved
  266.     it to disk before leaving the word processor/text editor).
  267. .K19,30
  268. all clear?
  269. .WN
  270.     Now suppose we have (successfully) compiled and linked ~Iprogram1~N.
  271.     (our program will actually compile...without any error messages!)
  272.     
  273.     We have on disk ~Iprogram1.exe~N which we execute by issuing the command:
  274.     ~Iprogram1~N  and the program will print:
  275.                                              cursor waits for 2 numbers.
  276. ~r~I Enter two numbers (separated by a space) : ~N~I█~N
  277.  
  278.     ..we type:  ~I21~N ~I22~N          (leaving a space between).
  279.     then press the Enter (or Return) key and expect to get:
  280.  
  281. ~r~I The average of 21.000000 and 22.000000 is 21.500000~N
  282.  
  283.      Our program statement was:
  284.  
  285.       ~b~Iprintf("\n The average of %f and %f is %f",x,y,a);~N
  286.  
  287.       and the ~b~I%f~N gives 6 decimal places...by default ).
  288.  
  289.     Alas, what we get is:
  290. .W
  291. .R23C1
  292. ~r~I The average of 21.000000 and 22.000000 is 21.000000~N
  293. .K19,60
  294. mamma mia!
  295. .WN
  296.     Let's look at the function ~b~Iaverage()~N again:
  297.  
  298. ~b~Iaverage(x,y)~N
  299. ~b~Ifloat x,y;~N
  300. ~b~I{~N  
  301. ~b~Ifloat z;~N
  302. ~b~Iz=(x+y)/2;~N
  303. ~b~Ireturn(z);~N
  304. ~b~I}~N
  305.                                ~IREMEMBER THIS:~N
  306.        ~V                                                                ~N
  307.        ~V ALL FUNCTIONS WILL RETURN AN INTEGER UNLESS YOU SAY OTHERWISE! ~N
  308.        ~V                                                                ~N
  309.  
  310.     ...so, the value of ~b~Iz~N which ~b~Iaverage()~N returned was changed
  311.     from 21.5 ( the ~b~Ifloat~Ning point average of the two floating point
  312.     numbers 21 and 22 ) to 21. The fractional part was truncated since
  313.     ( unless we ~Vsay otherwise~N ) our function returns an integer!
  314.  
  315.     And how do we tell the C-compiler that ~b~Iaverage()~N is to ~b~Ireturn~N
  316.     a ~b~Ifloat~Ning point number?
  317. .K3,60
  318. I give up!
  319. .WN
  320.     We write the ~b~Iaverage()~N function with a 
  321.     ~Itype declaration built into its name!~N
  322.  
  323. ~b~Ifloat average(x,y)~N          Note the ~b~Ifloat~N!
  324. ~b~Ifloat x,y;~N
  325. ~b~I{~N  
  326. ~b~Ifloat z;~N
  327. ~b~Iz=(x+y)/2;~n
  328. ~b~Ireturn(z);~N                  ~INow~N ~b~Ireturn(z)~N gives a ~b~Ifloat~N!
  329. ~b~I}~N
  330. .K19,60
  331.  finally!
  332. .WNT
  333.     FUNCTIONS HAVE A PRIVATE COPY OF THEIR ARGUMENTS    
  334. .R4C1
  335. ~b~Imain() {~N
  336. ~b~Ifloat x,y,a;~N
  337. ~b~Iprintf("\n Enter two numbers (separated by a space) : ");~N
  338. ~b~Iscanf("%f%f",&x,&y);~N   
  339. ~b~Ia=average(~Vx~N~b~I,~Vy~N~I);~N
  340. ~b~Iprintf("\n The average of %f and %f is %f",x,y,a);~N
  341. ~b~I}~N
  342. ~b~Iaverage(~Vx~N~b~I,~Vy~N~I);~N
  343. ~b~Ifloat x,y;~N
  344. ~b~I{~N  
  345. ~b~Ifloat z;~N
  346. ~b~Iz=(x+y)/2;~N
  347. ~b~Ireturn(z);~N
  348. ~b~I}~N
  349. .w
  350.    Although we called the two arguments of ~b~Iaverage()~N ~V x ~N and ~V y ~N
  351.    (just as ~b~Imain()~N did), this is not necessary!
  352.    The function ~b~Iaverage()~N only gets a ~Icopy~N of the variables which 
  353.    appear in its argument list and may give these copies any name it likes.
  354.    (they are NOT the ~Ioriginal~N ~V x ~N and ~V y ~N which ~b~Imain()~N uses!)
  355.    ~V The above program might be changed to read:~N
  356. .K12,60
  357.  MY copy
  358. .W
  359. .R4C1
  360. ~b~Imain() {~N
  361. ~b~Ifloat x,y,a;~N
  362. ~b~Iprintf("\n Enter two numbers (separated by a space) : ");~N
  363. ~b~Iscanf("%f%f",&x,&y);~N   
  364. ~b~Ia=average(x,y);~N
  365. ~b~Iprintf("\n The average of %f and %f is %f",x,y,a);~N
  366. ~b~I}~N
  367. ~Vfloat average(sam,sally)    ~N
  368. ~Vfloat sam, sally;           ~N
  369. ~V{                           ~N  
  370. ~Vfloat george;               ~N
  371. ~Vgeorge=(sam+sally)/2;       ~N
  372. ~Vreturn(george);             ~N
  373. ~V}                           ~N
  374. .K12,60
  375. sam+sally?
  376. .WNR2C1
  377.  Since ~Icopies~N of ~b~Ichar~N and ~b~Iint~N and ~b~Ifloat~N variables are passed
  378.  to a function, the function may manipulate these variables as it sees fit.
  379.  The ~Ioriginal~N values remain  unchanged.  This  mechanism  for calling
  380.  a function and passing variables is called : ~ICALL BY VALUE~N
  381. .b1-6
  382. .R8C1
  383.  The exception occurs when we pass a ~Istring~N variable to a function. In
  384.  this case, since a string may be arbitrarily long (!), it seems inefficient
  385.  to provide a ~Icopy~N of the string ... so C will pass the ~Iaddress~N in memory
  386.  where the string begins. This is called : ~ICALL BY REFERENCE~N
  387. .b7-12
  388. .R13
  389.     ~Icall by value~N is a mixed blessing. We cannot (for example) call upon
  390.     an ~b~Iexchange(x,y)~N function to exchange the values of the ~b~Iint~N
  391.     variables ~b~Ix~N and ~b~Iy~N
  392.  
  393. ~b~Iexchange(x,y)~N                    ~V                            ~N
  394. ~b~Iint x, y;~N                        ~V The values of x and y are  ~N
  395. ~b~I{~N                                ~V only exchanged within this ~N
  396. ~b~Iint temp;~N                        ~V function, NOT in main() !  ~N
  397. ~b~Itemp=x; x=y; y=temp; return;~N     ~V                            ~N
  398. ~b~I}~N
  399. .WK10,32
  400.   WHAT!
  401. .WN
  402. .R10C12
  403.  ... but don't despair, there are ways around this !
  404. .b8-12
  405. .K18,32
  406. can't wait
  407. .WN
  408.  
  409.  
  410. .T
  411.    That's all folks!   
  412.  
  413. .K16,32
  414. au revoir!
  415.  
  416.  
  417. .q
  418.  
  419.